package main

import  ( 
	"crypto/sha256"
	"encoding/hex"
	"strings"
	"strconv"
	"time"
	"fmt"
)

//Block区块链结构体
type Block struct{
	Index int //区块的索引（链中位置）

	Timestamp string //区块创建的时间戳

	Data string //区块链里存储的数据

	PrevHash string //前一个区块的哈希值

	Hash string //当前区块的哈希值

	Nonce int //随机数
}
//计算哈希值
func calculateHash(block Block) string {
	record := strconv.Itoa(block.Index) + block.Timestamp + block.Data + block.PrevHash + strconv.Itoa(block.Nonce)

	hasher := sha256.New()
	hasher.Write([]byte(record))
	hashed := hasher.Sum(nil)
	return hex.EncodeToString(hashed)

}

//挖矿：通过调整随机数找到符合难度要求的哈希值
func MineBlock(block Block, difficulty int) Block {
    //根据难度生成目标前缀（比如难度为3时，目标前缀为三个0）
   targetPrefix := strings.Repeat("0", difficulty)
   //无限循环，直到找到符合条件的哈希值
   for{
	//计算当前区块的哈希值
	block.Hash = calculateHash(block)
	//检查哈希值是否以目标前缀开头
	if strings.HasPrefix(block.Hash, targetPrefix) {
	    //如果哈希值以目标前缀开头，说明挖矿成功
		fmt.Printf("挖矿成功！！！ Nonce:%v\n Hash:%v\n", block.Nonce, block.Hash)
		break
	}
	//未满足条件，Nonce++直到找到
	block.Nonce++
   }
   return block
}

func main() {
    block := Block{
		Index: 1,
		Timestamp: time.Now().String(),
		Data: "李佳奇23603219",
		PrevHash: "0",
		Nonce: 0,
    }
	fmt.Printf("开始挖矿............")
	startTime := time.Now() //记录挖矿开始时间
	difficulty := 4//难度设置为4
	//调用挖矿函数
	MineBlock := MineBlock(block, difficulty)
	//计算挖矿耗时
	fmt.Printf("挖矿耗时：%v\n",time.Since(startTime))
	//打印区块信息
	fmt.Printf("区块信息：\n")
	fmt.Printf("索引：%v\n,数据：%v\n",MineBlock.Index,MineBlock.Data)
}